package com.rex.saas.controller;

import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.rex.saas.bean.BaseResponse;
import com.rex.saas.bean.DeviceBasicData;
import com.rex.saas.bean.ResultCode;
import com.rex.saas.bean.request.AiDeviceControlRequest;
import com.rex.saas.bean.request.WriteDevPropertyRequest;
import com.rex.saas.db.entity.PaasGatewayDeviceRelation;
import com.rex.saas.db.entity.SaasSpaceDevicePosition;
import com.rex.saas.db.entity.SaasSpaceDeviceRelation;
import com.rex.saas.service.AiService;
import com.rex.saas.service.GatewayService;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("/ai")
public class AiController extends BaseController{
    @Autowired
    private AiService aiService;

    private static final HashMap<String, String> propertyMap = new HashMap<>();
    static {
        propertyMap.put("温度", "temperature");
        propertyMap.put("湿度", "humidity");
        propertyMap.put("亮度", "light");
        propertyMap.put("音量", "sound");
        propertyMap.put("风速", "speed");
        propertyMap.put("模式", "mod");
    }

    @PostMapping("/device/control")
    public BaseResponse deviceControl(HttpServletRequest request, @RequestBody AiDeviceControlRequest aiDeviceControlRequest){
        log.info("deviceControl:{}", aiDeviceControlRequest);
        String token = request.getHeader("token");
        if (StringUtils.isEmpty( aiDeviceControlRequest.getAction())){
            log.error("action is null, aiDeviceControlRequest:{}", aiDeviceControlRequest);
            return BaseResponse.error("action is null", ResultCode.PARAM_ERROR);
        }

        if (StringUtils.isEmpty( aiDeviceControlRequest.getDeviceType())){
            log.error("deviceType is null, aiDeviceControlRequest:{}", aiDeviceControlRequest);
            return BaseResponse.error("device_type is null", ResultCode.PARAM_ERROR);
        }
        if (StringUtils.isEmpty( aiDeviceControlRequest.getDeviceId())){
            log.error("deviceId is null, aiDeviceControlRequest:{}", aiDeviceControlRequest);
            return BaseResponse.error("deviceId is null", ResultCode.PARAM_ERROR);
        }

        String gwName = aiDeviceControlRequest.getDeviceId().replace(":", "").toUpperCase();
        boolean flag = false;
        if (!StringUtils.isEmpty(aiDeviceControlRequest.getRoom())
                && !"未知".equals(aiDeviceControlRequest.getRoom())
                && !aiDeviceControlRequest.getDeviceType().equals(aiDeviceControlRequest.getRoom())){
            List<SaasSpaceDevicePosition> saasSpaceDevicePositions = deviceService.getDeviceByPosition(null, JwtUtils.getTenantId( token));
            if(!CollectionUtils.isEmpty(saasSpaceDevicePositions)){
                for (SaasSpaceDevicePosition saasSpaceDevicePosition : saasSpaceDevicePositions){
                    if (saasSpaceDevicePosition.getPosition().contains(aiDeviceControlRequest.getRoom())
                            && saasSpaceDevicePosition.getPosition().contains(aiDeviceControlRequest.getDeviceType())){
                        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(saasSpaceDevicePosition.getDeviceName(), token);
                        if(deviceBasicData==null){
                            log.error("getDeviceByDeviceName error, saasSpaceDeviceRelation.deviceName:{}", saasSpaceDevicePosition.getDeviceName());
                            continue;
                        }
                        WriteDevPropertyRequest writeDevPropertyRequest = getWriteDevPropertyRequest(deviceBasicData, aiDeviceControlRequest, saasSpaceDevicePosition.getRouter());
                        boolean result = deviceService.writeDevProperty(deviceBasicData, token, writeDevPropertyRequest);
                        if(!result){
                            log.error("writeDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
                            return BaseResponse.error("设备执行失败", ResultCode.SYSTEM_ERROR);
                        }
                        flag = true;
                    }
                }
            }else {
                log.warn("getDeviceByPosition is empty error, aiDeviceControlRequest:{}", aiDeviceControlRequest);
                List<SaasSpaceDeviceRelation> saasSpaceDeviceRelations = deviceService.getSpaceDeviceRelations(null, JwtUtils.getTenantId( token));
                if(CollectionUtils.isEmpty(saasSpaceDeviceRelations)){
                    log.error("deviceService.deviceInfoList is empty error, aiDeviceControlRequest:{}", aiDeviceControlRequest);
                    return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
                }
                for(SaasSpaceDeviceRelation saasSpaceDeviceRelation : saasSpaceDeviceRelations){
                    if (saasSpaceDeviceRelation.getPosition().contains(aiDeviceControlRequest.getRoom())
                            && saasSpaceDeviceRelation.getPosition().contains(aiDeviceControlRequest.getDeviceType())){
                        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(saasSpaceDeviceRelation.getDeviceName(), token);
                        if(deviceBasicData==null){
                            log.error("getDeviceByDeviceName error, getDeviceByDeviceName .deviceName:{}", saasSpaceDevicePositions.get(0).getDeviceName());
                            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
                        }
                        WriteDevPropertyRequest writeDevPropertyRequest = getWriteDevPropertyRequest(deviceBasicData, aiDeviceControlRequest, "1");
                        boolean result = deviceService.writeDevProperty(deviceBasicData, token, writeDevPropertyRequest);
                        if(!result){
                            log.error("writeDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
                            return BaseResponse.error("设备执行失败", ResultCode.SYSTEM_ERROR);
                        }
                        flag = true;
                    }
                }
            }
        }else {
            DeviceBasicData gateway = rexolarApiClient.getDeviceByDeviceName(gwName, token);
            if(gateway==null){
                log.error("getDeviceByDeviceName error, aiDeviceControlRequest.gwName:{}", gwName);
                return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
            }
            List<PaasGatewayDeviceRelation> deviceList = gatewayService.getSubDeviceList(gwName,gateway.getTenantId());
            if(CollectionUtils.isEmpty(deviceList)){
                log.error("gatewayService.getSubDeviceList is empty error, gwName:{}", gwName);
                return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
            }
            List<String> deviceNameList = deviceList.stream().map(PaasGatewayDeviceRelation::getDeviceName).collect(Collectors.toList());
            List<SaasSpaceDevicePosition> saasSpaceDevicePositions = deviceService.getDevicePositionByName(deviceNameList, JwtUtils.getTenantId( token));
            if(!CollectionUtils.isEmpty(saasSpaceDevicePositions)){
                for (SaasSpaceDevicePosition saasSpaceDevicePosition : saasSpaceDevicePositions){
                    if (saasSpaceDevicePosition.getPosition().contains(aiDeviceControlRequest.getDeviceType())){
                        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(saasSpaceDevicePosition.getDeviceName(), token);
                        if(deviceBasicData==null){
                            log.error("getDeviceByDeviceName error, saasSpaceDeviceRelation.deviceName:{}", saasSpaceDevicePosition.getDeviceName());
                            continue;
                        }
                        WriteDevPropertyRequest writeDevPropertyRequest = getWriteDevPropertyRequest(deviceBasicData, aiDeviceControlRequest, saasSpaceDevicePosition.getRouter());
                        boolean result = deviceService.writeDevProperty(deviceBasicData, token, writeDevPropertyRequest);
                        if(!result){
                            log.error("writeDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
                            return BaseResponse.error("设备执行失败", ResultCode.SYSTEM_ERROR);
                        }
                        flag = true;
                    }
                }
            }else {
                log.warn("getDeviceByPosition is empty error, aiDeviceControlRequest:{}", aiDeviceControlRequest);
                List<SaasSpaceDeviceRelation> saasSpaceDeviceRelations = deviceService.getSpaceDeviceRelations(null, JwtUtils.getTenantId( token));
                if(CollectionUtils.isEmpty(saasSpaceDeviceRelations)){
                    log.error("deviceService.deviceInfoList is empty error, aiDeviceControlRequest:{}", aiDeviceControlRequest);
                    return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
                }
                for(SaasSpaceDeviceRelation saasSpaceDeviceRelation : saasSpaceDeviceRelations){
                    if(!deviceNameList.contains(saasSpaceDeviceRelation.getDeviceName())){
                        continue;
                    }
                    if (saasSpaceDeviceRelation.getPosition().contains(aiDeviceControlRequest.getDeviceType())){
                        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(saasSpaceDeviceRelation.getDeviceName(), token);
                        if(deviceBasicData==null){
                            log.error("getDeviceByDeviceName error, getDeviceByDeviceName .deviceName:{}", saasSpaceDevicePositions.get(0).getDeviceName());
                            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
                        }
                        WriteDevPropertyRequest writeDevPropertyRequest = getWriteDevPropertyRequest(deviceBasicData, aiDeviceControlRequest, "1");
                        boolean result = deviceService.writeDevProperty(deviceBasicData, token, writeDevPropertyRequest);
                        if(!result){
                            log.error("writeDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
                            return BaseResponse.error("设备执行失败", ResultCode.SYSTEM_ERROR);
                        }
                        flag = true;
                    }
                }
            }
        }

        if (!flag){
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok();
    }

    private WriteDevPropertyRequest getWriteDevPropertyRequest(DeviceBasicData deviceInfo, AiDeviceControlRequest aiDeviceControlRequest, String number) {
        WriteDevPropertyRequest writeDevPropertyRequest = new WriteDevPropertyRequest();
        writeDevPropertyRequest.setDeviceName(deviceInfo.getName());
        writeDevPropertyRequest.setGroupId("0");
        if ("turnOn".equals(aiDeviceControlRequest.getAction())){
            writeDevPropertyRequest.setProperty("PowerSwitch_"+number);
            writeDevPropertyRequest.setValue("1");
        }else if ("turnOff".equals(aiDeviceControlRequest.getAction())){
            writeDevPropertyRequest.setProperty("PowerSwitch_"+number);
            writeDevPropertyRequest.setValue("0");
        }else if ("setDeviceProperty".equals(aiDeviceControlRequest.getAction())){
            String property = propertyMap.get(aiDeviceControlRequest.getProperty());
            if (property==null){
                log.error("propertyMap.get is null, property:{}", property);
            }
            writeDevPropertyRequest.setProperty(property+"_"+number);
            writeDevPropertyRequest.setValue(aiDeviceControlRequest.getLevel());
        }
        return writeDevPropertyRequest;
    }

    @PostMapping("/t2t")
    public BaseResponse t2t(HttpServletRequest request,  @RequestParam String str){
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("list tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        try {
            return BaseResponse.ok(aiService.t2t(str));
        } catch (NoApiKeyException e) {
            return BaseResponse.error("ApiKey异常", ResultCode.PARAM_ERROR);
        } catch (InputRequiredException e) {
            return BaseResponse.error(ResultCode.SYSTEM_ERROR);
        }
    }

    @PostMapping("/t2t2")
    public BaseResponse t2t2(HttpServletRequest request,  @RequestParam String str){
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isEmpty(tenantId)){
            log.error("list tenantId is null,spaceInfoId:{}", tenantId);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        try {
            return BaseResponse.ok(aiService.t2t2(str));
        } catch (NoApiKeyException e) {
            return BaseResponse.error("ApiKey异常", ResultCode.PARAM_ERROR);
        } catch (InputRequiredException e) {
            return BaseResponse.error(ResultCode.SYSTEM_ERROR);
        }
    }
}

